package com.jet.auth.service;

import com.jet.merchant.domain.bo.LoginBo;
import com.jet.core.exception.CustomException;
import com.jet.leaf.service.MerchantCodeGenerate;
import com.jet.merchant.domain.enums.BasicConfigConst;
import com.jet.merchant.domain.dto.RegisterDto;
import com.jet.merchant.service.IClerkAccountService;
import com.jet.merchant.service.IMerchantService;
import com.jet.merchant.service.IMerchantStoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Service
@Slf4j
public class GenerateService {
    @Resource
    private SmsCaptchaService smsCaptchaService;

    @Resource
    private AuthService authService;

    @Resource
    private MerchantCodeGenerate merchantCodeGenerate;

    private final IMerchantService merchantService;
    private final IMerchantStoreService merchantStoreService;
    private final IClerkAccountService clerkAccountService;

    public GenerateService(IMerchantService merchantService, IMerchantStoreService merchantStoreService, IClerkAccountService clerkAccountService) {
        this.merchantService = merchantService;
        this.merchantStoreService = merchantStoreService;
        this.clerkAccountService = clerkAccountService;
    }

    /**
     * 注册用户并返回登录信息
     *
     * @param request HttpServletRequest对象，用于获取请求信息
     * @param dto     注册所需信息的DTO对象
     * @return 登录信息对象LoginVo
     * @throws CustomException 如果短信验证码验证失败或手机号已存在则抛出此异常
     * @Transactional(rollbackFor = CustomException.class) 使用事务注解，当方法内发生CustomException异常时，将回滚事务
     */
    @Transactional(rollbackFor = Exception.class)
    public LoginBo register(HttpServletRequest request, RegisterDto dto) {
        smsCaptchaService.validSmsCaptcha(dto.getPhone(), dto.getSmsCaptcha());
        validExists(dto.getPhone());
        long merchantNo = createCode();
        long storeNo = BasicConfigConst.STORE_START_NO + 1;

        String accountId = clerkAccountService.register(merchantNo, storeNo, dto.getPhone(), null);
        merchantService.register(merchantNo, storeNo, accountId, dto);
        merchantStoreService.register(merchantNo, storeNo, accountId, dto.getPhone());
        // 注册自动登录
        return authService.registerLogin(request, dto.getPhone(), dto.getSource());
    }

    /**
     * 注册新用户
     *
     * @param dto 注册新用户所需的参数对象
     * @throws Exception 当注册新用户过程中发生异常时抛出
     * @Transactional(rollbackFor = Exception.class) 使用事务注解，当方法内发生异常时，将回滚事务
     */
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterDto dto) {
        validExists(dto.getPhone());
        long merchantNo = createCode();
        long storeNo = BasicConfigConst.STORE_START_NO + 1;
        String accountId = clerkAccountService.register(merchantNo, storeNo, dto.getPhone(), dto.getOpenId());
        merchantService.register(merchantNo, storeNo, accountId, dto);
        merchantStoreService.register(merchantNo, storeNo, accountId, dto.getPhone());
    }

    public long createCode() {
        do {
            long code = merchantCodeGenerate.create();
            if (!merchantService.existsMerchantNo(code)) {
                return code;
            }
        } while (true);
    }

    private void validExists(String phone) {
        boolean existsAccount = clerkAccountService.existByPhone(phone);
        if (existsAccount) {
            throw new CustomException("注册失败：手机号已注册");
        }
    }
}
